package fun.codedesign.jdk.thread;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*;

public class CountDownLatchTest {

    /**
     * future.get() 本身就是阻塞的，所以不需要使用CountDownLatch.await进行阻塞
     *
     * @param args
     * @throws InterruptedException
     * @throws ExecutionException
     */
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        int num = 10;
        CountDownLatch begin = new CountDownLatch(1);
        CountDownLatch end = new CountDownLatch(num);
        // 固定数量线程池
        ExecutorService es = Executors.newFixedThreadPool(10);
        // 装线程返回值
        List<Future<Integer>> list = new ArrayList<Future<Integer>>();
        for (int i = 0; i < num; i++) {
            list.add(es.submit(new ScoreBuilder(begin, end)));
        }
        // 配合线程中的await使用，这里-1后，线程中开始同步执行生成分数
        begin.countDown();
        // end不为0则阻塞在这里，等待所有线程执行完成
        //end.await();
        es.shutdown();
        int count = 0;
        // future本身就是阻塞的，可以需要使用countDown
        for (Future<Integer> future : list) {
            count += future.get();
        }
        // 135314105
        System.out.println(count / num);
    }


    static class ScoreBuilder implements Callable<Integer> {
        private CountDownLatch begin;
        private CountDownLatch end;

        public ScoreBuilder(CountDownLatch begin, CountDownLatch end) {
            this.begin = begin;
            this.end = end;
        }

        @Override
        public Integer call() throws Exception {
            begin.await();
            System.out.println("线程开始执行时间：" + System.nanoTime());
            int score = new Random(30).nextInt();
            // Thread.sleep(5000);
            // end -1
            end.countDown();
            // System.out.println("执行完成"+ end.getCount());
            return score;
        }

    }
}
